//
//  ARDiscoverWorkDetailController.swift
//  AquaRaft
//
//  Created by 何启亮 on 2024/4/22.
//

import UIKit
import JKSwiftExtension
import SnapKit
import Kingfisher
import AVFoundation

/// 从discover进来的作品
class ARDiscoverWorkDetailController: ARBaseViewController {

    // MARK: - Property
    
    let workId: String
    let viewModel: ARWorkDetailViewModel
    let style = ARWorkDetailPathStyle.discover
    
    private static let cellReuseId = "ar.discoverWorkDetailPage.cellReuseId"
    private static let commentCellReuseId = "ar.discoverWorkDetailPage.commentCellReuseId"
    private static let commentSectionHeaderReuseId = "ar.discoverworkdetailpage.commentsectionheaderreuseid"
    
    private weak var audioRecordVc: ARAudioRecordController?
    
    // MARK: - Init
    
    init(workId: String) {
        self.workId = workId
        self.viewModel = ARWorkDetailViewModel(workId: workId, style: self.style)
        
        super.init(nibName: nil, bundle: nil)
        
        self.viewModel.audioDelegate = self
        
        self.fd_prefersNavigationBarHidden = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - LifeCycle
    
    override func viewDidLoad() {
        super.viewDidLoad()

        setupUI()
        loadData()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 暂停播放
        viewModel.stopCurrentPlayer()
    }
    
    // MARK: - UI
    
    private func setupUI() {
        
        self.view.backgroundColor = .white
        
        tableHeaderView.addSubview(picsCollectionView)
        tableHeaderView.addSubview(contentView)
        tableHeaderView.addSubview(avatarBtn)
        tableHeaderView.addSubview(followBtn)
        
        contentView.addSubview(titleLabel)
        contentView.addSubview(workContentView)
        contentView.addSubview(translateBtn)
        contentView.addSubview(translateActivityView)
        contentView.addSubview(giftBtn)
        contentView.addSubview(likeBtn)
        
        self.view.addSubview(tableView)
        tableView.tableHeaderView = tableHeaderView
        self.view.addSubview(backBtn)
        self.view.addSubview(moreBtn)
        
        self.addChild(inputVc)
        self.view.addSubview(inputVc.view)
        
        // setup header view
        picsCollectionView.snp.makeConstraints { make in
            make.top.right.left.equalToSuperview()
            make.width.equalTo(ARHelper.screenWidth())
            make.height.equalTo(ARHelper.screenWidth() * (367.0 / 375.0))
        }
        
        contentView.snp.makeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.top.equalTo(picsCollectionView.snp.bottom).offset(-42)
            // 高度由内容决定
        }
        
        avatarBtn.snp.makeConstraints { make in
            make.width.height.equalTo(48)
            make.centerY.equalTo(contentView.snp.top)
            make.right.equalToSuperview().offset(-32)
        }
        
        followBtn.snp.makeConstraints { make in
            make.width.height.equalTo(14)
            make.bottom.equalTo(avatarBtn).offset(-2)
            make.right.equalTo(avatarBtn).offset(-2)
        }
        
        // setup workcontentview 内容
        titleLabel.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(32)
            make.right.equalToSuperview().offset(-32)
            make.top.equalToSuperview().offset(40)
            // 高度由内容决定
        }

        workContentView.snp.makeConstraints { make in
            make.left.right.equalTo(titleLabel)
            make.top.equalTo(titleLabel.snp.bottom).offset(18)
            // 高度由内容决定
        }
        
        likeBtn.snp.makeConstraints { make in
            make.width.height.equalTo(24)
            make.right.equalToSuperview().offset(-30)
            make.top.equalTo(workContentView.snp.bottom).offset(24)
            make.bottom.equalToSuperview().offset(-(8+20))
        }
        
        giftBtn.snp.makeConstraints { make in
            make.centerY.equalTo(likeBtn)
            make.right.equalTo(likeBtn.snp.left).offset(-20)
            make.width.height.equalTo(24)
        }
        
        translateBtn.snp.makeConstraints { make in
            make.left.equalTo(workContentView)
            make.centerY.equalTo(likeBtn)
        }
        
        translateActivityView.snp.makeConstraints { make in
            make.left.equalTo(translateBtn)
            make.centerY.equalTo(translateBtn)
        }
        
        // tableview
        tableView.snp.makeConstraints { make in
            make.left.right.top.equalToSuperview()
            make.bottom.equalTo(inputVc.view.snp.top)
        }
        
        backBtn.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(20)
            make.top.equalToSuperview().offset(8 + ARHelper.statusBarHeight())
            make.width.height.equalTo(28)
        }
        
        moreBtn.snp.makeConstraints { make in
            make.width.height.equalTo(30)
            make.right.equalToSuperview().offset(-20)
            make.centerY.equalTo(backBtn)
        }
        
        inputVc.view.snp.makeConstraints { make in
            make.left.right.equalToSuperview()
            make.bottom.equalToSuperview().offset(-ARHelper.safeBottomHeight())
            // 自适应高度
        }
        
        // 初始高度
        let height = tableHeaderView.systemLayoutSizeFitting(.init(width: ARHelper.screenWidth(), height: CGFloat.greatestFiniteMagnitude)).height
        tableHeaderView.frame = .init(x: 0, y: 0, width: ARHelper.screenWidth(), height: height)
    }
    
    // MARK: - Action
    
    @objc private func likeBtnCliked(_ sender: UIButton) {
        self.ar.showLoading()
        viewModel.likeOrUnLikeWork { [weak self] err in
            guard let self = self else {
                return
            }
            self.ar.hideHUD()
            if let err = err {
                self.ar.makeToast(err.localizedDescription)
                return
            }
            
            // 成功 - 更新
            self.updateVcValue()
        }
    }
    
    @objc private func moreBtnCliked(_ sender: UIButton) {
        guard let user = viewModel.workModel?.author else {
            return
        }
        ARUserRelationshipHelper.workMoreAction(user: user, vc: self) { [weak self] type, err in
            if let err = err {
                self?.ar.makeToast(err.localizedDescription)
                return
            }
            switch type {
            case .blackList:
                // 黑名单 - 返回
                self?.ar_transitionToBack()
            case .follow:
                // 成功 - 更新cell
                self?.updateVcValue()
            }
        }
    }
    
    @objc private func avatarBtnClicked(_ sender: UIButton) {
        guard let userId = viewModel.workModel?.authorId else {
            return
        }
        self.navigationController?.pushViewController(ARPersonalPageController(userId: userId), animated: true)
    }
    
    @objc private func followBtnClicked(_ sender: UIButton) {
        guard let userId = viewModel.workModel?.authorId else {
            return
        }
        self.ar.showLoading()
        viewModel.followUser(userId) { [weak self] err in
            self?.ar.hideHUD()
            if let err = err {
                self?.ar.makeToast(err.localizedDescription)
                return
            }
            
            // 刷新一下
            self?.ar.makeToast(ARHelper.localString("Follow Successfully"))
            self?.updateVcValue()
        }
    }
    
    @objc private func giftBtnClicked(_ sender: UIButton) {
        guard let userId = viewModel.workModel?.authorId else {
            return
        }
        
        ARHelper.window().ar.topViewController()?.present(ARSendGiftController(purchseFor: userId), animated: true)
    }
    
    @objc private func translateBtnClicked(_ sender: UIButton) {
        if sender.isHidden {
            return
        }
        guard let work = viewModel.workModel else {
            return
        }
        // 开始翻译
        sender.isHidden = true
        translateActivityView.isHidden = false
        translateActivityView.startAnimating()
        ARTranslateUtil.share.translate(work.workDescription) { [weak self] result in
            switch result {
            case .faild(let err):
                self?.translateActivityView.stopAnimating()
                self?.translateActivityView.isHidden = true
                self?.translateBtn.isHidden = false
                self?.ar.makeToast(err.localizedDescription)
            case .successWithoutResponse:
                self?.translateActivityView.stopAnimating()
                self?.translateActivityView.isHidden = true
                self?.translateBtn.isHidden = false
            case .success(_):
                self?.translateActivityView.stopAnimating()
                self?.translateActivityView.isHidden = true
                self?.updateVcValue()
            }
        }
    }
    
    // MARK: -
    
    private func loadData() {
        self.ar.showLoading()
        viewModel.fetchWork { [weak self] err in
            guard let self = self else {
                return
            }
            self.ar.hideHUD()
            if let err = err {
                self.ar.makeToast(err.localizedDescription)
                return
            }
            
            self.updateVcValue()
            if ARConfigManager.share.autoTranslate {
                // 自动翻译
                self.translateBtnClicked(self.translateBtn)
            }
        }
    }
    
    /// 更新数据
    private func updateVcValue() {
        guard let work = viewModel.workModel else {
            return
        }
        titleLabel.text = work.workTitle
        likeBtn.isSelected = (work.isLike ?? false)
        
        let translatedText = ARTranslateUtil.share.translatedTextFor(work.workDescription)
        workContentView.update(content: work.workDescription, translateContent: translatedText)
        if translatedText != nil {
            translateBtn.isHidden = true
        } else {
            translateBtn.isHidden = false
        }
        
        if let avatarUrl = work.author?.trueAvatar,
           let url = URL(string: avatarUrl) {
            avatarBtn.kf.setImage(with: url, for: .normal)
        }
        if work.authorId ?? "" == ARUserManager.shared.userId ?? "" {
            followBtn.isHidden = true
        } else {
            followBtn.isHidden = work.author?.isFollow ?? false
        }
        
        moreBtn.isHidden = work.isCurrentUser()
        giftBtn.isHidden = work.isCurrentUser()
        
        // 更新高度
        let height = tableHeaderView.systemLayoutSizeFitting(.init(width: ARHelper.screenWidth(), height: CGFloat.greatestFiniteMagnitude)).height
        tableHeaderView.frame = .init(x: 0, y: 0, width: ARHelper.screenWidth(), height: height)
        
        picsCollectionView.reloadData()
        tableView.reloadData()
    }
    
    // MARK: - Lazy
    
    private lazy var backBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.addTarget(self, action: #selector(ar_transitionToBack), for: .touchUpInside)
        btn.setImage(.init(named: "common_nav_new_back_white_icon"), for: .normal)
        return btn
    }()
    
    private lazy var moreBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.addTarget(self, action: #selector(moreBtnCliked(_:)), for: .touchUpInside)
        btn.setImage(.init(named: "common_more"), for: .normal)
        return btn
    }()
    
    private lazy var tableHeaderView: UIView = {
        let tableHeaderView = UIView()
        tableHeaderView.backgroundColor = .white
        return tableHeaderView
    }()
    
    private lazy var picsCollectionView: UICollectionView = {
        let flow = UICollectionViewFlowLayout()
        flow.itemSize = .init(width: ARHelper.screenWidth(), height: ARHelper.screenWidth() * (367.0 / 375.0))
        flow.scrollDirection = .horizontal
        flow.minimumLineSpacing = 0
        flow.minimumInteritemSpacing = 0
        
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: flow)
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: Self.cellReuseId)
        
        collectionView.isPagingEnabled = true
        collectionView.backgroundColor = .white
        return collectionView
    }()
    
    private lazy var avatarBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.addTarget(self, action: #selector(avatarBtnClicked(_:)), for: .touchUpInside)
        btn.layer.cornerRadius = 24
        btn.layer.masksToBounds = true
        btn.layer.borderColor = UIColor.white.cgColor
        btn.layer.borderWidth = 1
        return btn
    }()
    
    private lazy var followBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.addTarget(self, action: #selector(followBtnClicked(_:)), for: .touchUpInside)
        btn.setImage(.init(named: "common_follow_icon"), for: .normal)
        return btn
    }()
    
    /// 作品内容的View
    private lazy var contentView: UIView = {
        
        let separatorView = UIView()
        separatorView.backgroundColor = .init(hexString: "#F6F7F8")
        
        let view = UIView()
        view.backgroundColor = .white
        view.addSubview(separatorView)
        
        view.layer.cornerRadius = 40
        view.layer.masksToBounds = true
        view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
        
        separatorView.snp.makeConstraints { make in
            make.bottom.left.right.equalToSuperview()
            make.height.equalTo(8)
        }
        
        return view
    }()
    
    private lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.numberOfLines = 1
        label.font = ARHelper.font(16, weight: .medium)
        label.textColor = .init(hexString: "#404040")
        return label
    }()
    
    private lazy var workContentView: ARWorkContentWithTranslateView = {
        // 内容view
        let view = ARWorkContentWithTranslateView()
        return view
    }()
    
    private lazy var likeBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.setImage(.init(named: "common_like_btn_normal"), for: .normal)
        btn.setImage(.init(named: "common_like_btn_selected"), for: .selected)
        btn.titleLabel?.font = ARHelper.font(18, weight: .medium)
        btn.setTitleColor(.white, for: .normal)
        btn.addTarget(self, action: #selector(likeBtnCliked(_:)), for: .touchUpInside)
        return btn
    }()
    
    private lazy var giftBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.setImage(.init(named: "common_gift_icon"), for: .normal)
        btn.addTarget(self, action: #selector(giftBtnClicked(_:)), for: .touchUpInside)
        return btn
    }()
    
    private lazy var translateBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.setImage(.init(named: "workDetail_translate_icon"), for: .normal)
        btn.setTitle(ARHelper.localString("Translate"), for: .normal)
        btn.setTitleColor(.init(hexString: "#999999"), for: .normal)
        btn.titleLabel?.font = ARHelper.font(10, weight: .regular)
        btn.addTarget(self, action: #selector(translateBtnClicked(_:)), for: .touchUpInside)
        btn.jk.setImageTitleLayout(.imgLeft, spacing: 7)
        return btn
    }()
    
    private lazy var translateActivityView: UIActivityIndicatorView = {
        let view = UIActivityIndicatorView.init(style: .medium)
        view.isHidden = true
        return view
    }()
    
    private lazy var tableView: UITableView = {
        var tableView = UITableView.init(frame: .zero, style: .plain)
        tableView.backgroundColor = .clear
        tableView.dataSource = self
        tableView.delegate = self
        tableView.separatorStyle = .none
        tableView.isScrollEnabled = true
        tableView.register(ARWorkCommentCell.self, forCellReuseIdentifier: Self.commentCellReuseId)
        tableView.register(ARWorkCommentSectionHeaderView.self, forHeaderFooterViewReuseIdentifier: Self.commentSectionHeaderReuseId)
        tableView.estimatedRowHeight = 116
        return tableView
    }()
    
    private lazy var inputVc: ARCommentInputController = {
        let vc = ARCommentInputController(functions: [.text, .audio])
        vc.separatorLine.isHidden = false
        vc.delegate = self
        return vc
    }()
}

// MARK: -

extension ARDiscoverWorkDetailController: UICollectionViewDelegate, UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Self.cellReuseId, for: indexPath)
        
        // 判断是否有UIImageView
        var imageView = cell.viewWithTag(1124)
        if imageView == nil {
            imageView = UIImageView()
            imageView?.tag = 1124
            cell.contentView.addSubview(imageView!)
            imageView!.snp.makeConstraints { make in
                make.edges.equalToSuperview()
            }
            
            imageView?.contentMode = .scaleAspectFill
            imageView?.layer.masksToBounds = true
        }
        
        if let patchs = self.viewModel.workModel?.realPicsPath() {
            (imageView as? UIImageView)?.ar.setImage(patchs[indexPath.item])
        }
        
        return cell
    }
    
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.viewModel.workModel?.realPicsPath()?.count ?? 0
    }
}

extension ARDiscoverWorkDetailController: UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.comment.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let model = viewModel.comment[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: Self.commentCellReuseId, for: indexPath) as! ARWorkCommentCell
        cell.celldData = model
        cell.selectionStyle = .none
        
        cell.likeBtnClickedCallback = { [weak self] aCell in
            guard let cellData = aCell.celldData else {
                return
            }
            self?.ar.showLoading()
            self?.viewModel.likeOrUnLikeComment(cellData.commentModel.id, like: !cellData.commentModel.isLike, completion: { err in
                self?.ar.hideHUD()
                if let err = err {
                    self?.ar.makeToast(err.localizedDescription)
                    return
                }
                
                // 成功 - 刷新
                aCell.celldData = cellData
            })
        }
        
        cell.audioClickedCallback = { [weak self] cellData in
            self?.viewModel.playOrStopAudio(cellData)
        }
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let model = viewModel.comment[indexPath.row]
        return model.cellHeight
    }
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        self.view.endEditing(true)
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        if section == 0 {
            return 16 + 24 + 16
        }
        return 0.01
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: Self.commentSectionHeaderReuseId) as! ARWorkCommentSectionHeaderView
        header.titleLabel.text = "\(ARHelper.localString("Comment"))（\(self.viewModel.comment.count)）"
        return header
    }
    
}

extension ARDiscoverWorkDetailController: ARCommentInputControllerDelegate {
    
    func inputVc(_ vc: ARCommentInputController, sentVale: ARCommentInputController.InputValue) {
        
        if case.text(let sendText) = sentVale {
            // 只处理text
            ARHelper.window().ar.showLoading()
            self.viewModel.postTextComment(sendText) { [weak self] err in
                guard let self = self else {
                    return
                }
                ARHelper.window().ar.hideHUD()
                if let err = err {
                    ARHelper.window().ar.makeToast(err.localizedDescription)
                    return
                }
                // 成功
                self.inputVc.clearText()
                self.updateVcValue()
                DispatchQueue.main.async {
                    self.tableView.jk.scrollToBottom(animated: true)
                }
            }
        }
        
    }
    
    func inputVc(_ vc: ARCommentInputController, recordGestureDidChange gesture: UILongPressGestureRecognizer) {
        
        func showAudioRecordVc() {
            if self.audioRecordVc != nil {
                self.audioRecordVc?.dismiss(animated: true)
            }
            let vc = ARAudioRecordController(recordPath: ARFileHelper.createAudioPath(), delegate: self)
            self.present(vc, animated: true)
            self.audioRecordVc = vc
            // 回调
            vc.gestureChangeCallback(gesture)
        }
        
        switch gesture.state {
        case .began:
            // 判断权限
            let status = AVCaptureDevice.authorizationStatus(for: .audio)
            switch status {
            case .notDetermined:
                gesture.state = .cancelled
                AVCaptureDevice.requestAccess(for: .audio) { [weak self] author in
                    if !author {
                        self?.ar.makeToast(ARHelper.localString("No permission"))
                        return
                    }
                    
                    // 成功 - Do nothing...
                }
            case .authorized:
                showAudioRecordVc()
            default:
                gesture.state = .cancelled
            }
            
        default:
            self.audioRecordVc?.gestureChangeCallback(gesture)
        }
        
    }
    
}

extension ARDiscoverWorkDetailController: ARAudioRecordControllerDelegate {
    
    /// 录音结束回调
    func audioRecordControllerDidEndRecord(_ vc: ARAudioRecordController, audioPath: String, duration: TimeInterval) {
        if duration < 1 {
            self.ar.makeToast(ARHelper.localString("The recording time cannot be less than 1s"))
            return
        }
        
        ARHelper.window().ar.showLoading()
        self.viewModel.postAudioComment(audioPath, duration: duration) { [weak self] err in
            guard let self = self else {
                return
            }
            ARHelper.window().ar.hideHUD()
            if let err = err {
                ARHelper.window().ar.makeToast(err.localizedDescription)
                return
            }
            // 成功
            self.inputVc.clearText()
            self.updateVcValue()
            DispatchQueue.main.async {
                self.tableView.jk.scrollToBottom(animated: true)
            }
        }
    }
    
    /// 回调错误
    func audioRecordControllerDidEndRecord(_ vc: ARAudioRecordController, withError err: Error?) {
        
        if let err = err {
            self.ar.makeToast(err.localizedDescription)
        }
    }
    
}

extension ARDiscoverWorkDetailController: ARWorkDetailViewModelAudioOperationDelegate {
    func viewModel(_ viewModel: ARWorkDetailViewModel, shouldRefreshUI cellDatas: [ARWorkCommentCellData]) {
        
        // 查找cell
        for cell in self.tableView.visibleCells {
            guard let cell = cell as? ARWorkCommentCell else {
                continue
            }
            
            for cellData in cellDatas {
                if cell.celldData == cellData {
                    cell.celldData = cellData
                }
            }
        }
        
    }
    
    func viewModel(_ viewModel: ARWorkDetailViewModel, playAudioError error: Error?) {
        if let err = error {
            self.ar.makeToast(err.localizedDescription)
        }
    }
    
    
}
